package com.zp.qualitypractice.list.header;

import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.zp.qualitypractice.R;
import com.zp.qualitypractice.list.CustomLoadingView;

/**
 * Created by izp on 2017/4/22.
 */

public class HeaderView extends LinearLayout{
    private View mHeaderContent;
    private TextView mHeaderHint;
    private ImageView mHeaderArrow;
    private CustomLoadingView mLoadingView;

    private RotateAnimation mRotateUp;
    private RotateAnimation mRotateDown;

    private int mMeasureHeight;
    private int mState;
    //没有任何的状态
    public final static int STATE_NORMAL = 0;
    //准备刷新的状态
    private final int STATE_RELEASE_TO_REFRESH = 1;
    //正在刷新的状态
    public final static int STATE_REFRESHING = 2;
    //刷新结束的状态
    public final static int STATE_DONE = 3;

    public HeaderView(Context context) {
        super(context);
        init(context);
    }

    public HeaderView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public HeaderView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public HeaderView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        init(context);
    }

    private void init(Context context){
        mHeaderContent = LayoutInflater.from(context).inflate(R.layout.item_bubble_loading_header,null,false);
        LayoutParams layoutParams = new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        layoutParams.setMargins(0,0,0,0);//
//        给当前父LinearLayout设置margin，
        setLayoutParams(layoutParams);
        setPadding(0,0,0,0);//给当前父LinearLayout设置padding
        addView(mHeaderContent,new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,0));
//        添加一个view，并把它的高度设置为0
        setGravity(Gravity.BOTTOM);//现在基本上可以确定item_bubble_loading_header这个布局是多此一举了
        mHeaderHint = (TextView) findViewById(R.id.tv_hint);
        mHeaderArrow = (ImageView) findViewById(R.id.iv_arrow);

        mLoadingView = (CustomLoadingView) findViewById(R.id.loadingProgress);

//        定义一个向上旋转的动画
        /*pivotXType, pivotXValue, pivotYType, pivotYValue  旋转点类型及其值。
        Animation.ABSOLUTE为绝对值 其他为百分比。这个和平移动画的一样，*/
        mRotateUp = new RotateAnimation(0f,-180f, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        mRotateUp.setDuration(180);
        mRotateUp.setFillAfter(true);//设置旋转后保持旋转的状态

        mRotateDown = new RotateAnimation(-180f,0f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
        mRotateDown.setDuration(180);
        mRotateDown.setFillAfter(true);

//        手动调用测量的作用？
        measure(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
//        难道调用这个就能获得准确的宽高值？
        mMeasureHeight = getMeasuredHeight();

    }

    public void setState(int state){
        switch (state){
            case STATE_REFRESHING://正在刷新的状态
                mHeaderArrow.clearAnimation();
                mHeaderArrow.setVisibility(INVISIBLE);
                mLoadingView.setVisibility(VISIBLE);
                mHeaderHint.setText("正在刷新");
                break;
            case STATE_DONE://结束刷新的状态
                //刷新结束状态
                mHeaderArrow.setVisibility(View.INVISIBLE);
                mLoadingView.setVisibility(View.INVISIBLE);
                mHeaderHint.setText("刷新完成");
                break;
            case STATE_RELEASE_TO_REFRESH:
            case STATE_NORMAL:
                //正常状态隐藏进度条显示箭头
                mHeaderArrow.setVisibility(View.VISIBLE);
                mLoadingView.setVisibility(View.INVISIBLE);
                if (state ==STATE_NORMAL){
                    //如果当前状态是准备做刷新就开始动画
                    if (mState==STATE_RELEASE_TO_REFRESH){
                        mHeaderArrow.startAnimation(mRotateDown);
                    }
                    //如果当前状态正在刷新,就停止动画
                    if (mState==STATE_REFRESHING){
                        mHeaderArrow.clearAnimation();
                    }
                    mHeaderHint.setText("下拉刷新");
                }else if (mState!=STATE_RELEASE_TO_REFRESH){
                    mHeaderArrow.clearAnimation();
                    mHeaderArrow.startAnimation(mRotateUp);
                    mHeaderHint.setText("松开刷新");
                }
                break;
        }
        mState = state;
    }

    public int getState(){
        return mState;
    }

    /**
     * @return
     * 松开刷新后的动作
     */
    public boolean releaseAction(){
        //是否在刷新
        boolean isOnRefresh = false;
        int height = getVisibleHeight();
        if (height<=0){
            isOnRefresh = false;
        }
        if (height>mMeasureHeight && mState<STATE_REFRESHING){
            //如果当前可见高度大于测量高度，这个测量高度是在init的时候获取的，基本就是0，并且是准备刷新和刷新之前两个状态
            setState(STATE_REFRESHING);
            isOnRefresh = true;
        }
        int distanceHeight = 0;//如果不是正在刷新状态，那么就移动到隐藏header的地方
        if (mState == STATE_REFRESHING){
            //如果是正在刷新的状态，那么释放之后是移动到刷新View的高度上
            distanceHeight = mMeasureHeight;//这个measureHeight不会变么？
        }
        smoothScrollTo(distanceHeight);
        return isOnRefresh;
    }

    public void smoothScrollTo(int height){
        ValueAnimator animator = ValueAnimator.ofInt(getVisibleHeight(), height);
        animator.setDuration(300);
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator valueAnimator) {
                setVisibleHeight((Integer) valueAnimator.getAnimatedValue());
//                这个采用的方案仍然是动态改变contentView的高度，而不是移动到屏幕外界
            }
        });
        animator.start();
    }

    public void onMove(float heightF){
        if (getVisibleHeight() > 0 || heightF > 0){
            setVisibleHeight((int)heightF + getVisibleHeight());//当前显示高度+移动（正负）高度
            if (mState <= STATE_RELEASE_TO_REFRESH) { // 未处于刷新状态，更新箭头
                if (getVisibleHeight() > mMeasureHeight) {//如果当前的可见高度大于原本的高度，那么，现在的状态是准备刷新
                    setState(STATE_RELEASE_TO_REFRESH);
                }else {
                    setState(STATE_NORMAL);
                }
            }

        }
    }
    public void onRefreshComplete(){
        setState(STATE_DONE);
        new Handler().postDelayed(new Runnable() {//这里又是为什么要延迟更改状态
            @Override
            public void run() {
                reset();
            }
        }, 200);
    }

    public void reset(){
        smoothScrollTo(0);//动态设置高度到0
        new Handler().postDelayed(new Runnable() {//在已经看不到界面的情况下会什么要延迟修改View都得状态呢？
            @Override
            public void run() {
               setState(STATE_NORMAL);
            }
        },500);
    }

    public int getVisibleHeight(){
        LayoutParams layoutParams = (LayoutParams) mHeaderContent.getLayoutParams();
        return layoutParams.height;
    }

    public void setVisibleHeight(int height){
        if (height<0){
            height=0;
        }
        LayoutParams layoutParams = (LayoutParams) mHeaderContent.getLayoutParams();
        layoutParams.height=height;
        mHeaderContent.setLayoutParams(layoutParams);
    }


}
